#include "CCanvas.h"

CCanvas::CCanvas()
{
    m_klotski.m_fnGame(1);
    m_klotski.m_fnRestart();
    m_bEditing = false;
    m_iAdding = 0;
    m_lpRects[0].left = LEFT_X + GRID_SIZE * 4 + GRID_SIZE / 4;
    m_lpRects[0].right = m_lpRects[0].left + GRID_SIZE / 2;
    m_lpRects[0].top = TOP_Y + GRID_SIZE * 2 + GRID_SIZE / 4;
    m_lpRects[0].bottom = m_lpRects[0].top + GRID_SIZE / 2;
    m_lpRects[1].left = LEFT_X + GRID_SIZE * 5;
    m_lpRects[1].right = m_lpRects[1].left + GRID_SIZE;
    m_lpRects[1].top = TOP_Y + GRID_SIZE * 2 + GRID_SIZE / 4;
    m_lpRects[1].bottom = m_lpRects[1].top + GRID_SIZE / 2;
    m_lpRects[2].left = LEFT_X + GRID_SIZE * 4 + GRID_SIZE / 4;
    m_lpRects[2].right = m_lpRects[2].left + GRID_SIZE / 2;
    m_lpRects[2].top = TOP_Y + GRID_SIZE * 3;
    m_lpRects[2].bottom = m_lpRects[2].top + GRID_SIZE;
    m_lpRects[3].left = LEFT_X + GRID_SIZE * 5;
    m_lpRects[3].right = m_lpRects[3].left + GRID_SIZE;
    m_lpRects[3].top = TOP_Y + GRID_SIZE * 3;
    m_lpRects[3].bottom = m_lpRects[3].top + GRID_SIZE;

}

void CCanvas::OnMouseEvent(int x_mouse, int y_mouse)
{
    int x, y, i;
    if (!m_klotski.m_bSolving)
    {
        x = (x_mouse - LEFT_X) / GRID_SIZE;
        y = (y_mouse - TOP_Y) / GRID_SIZE;
        if (m_bEditing)
        {
            if (x >= 0 && x < 4 && y >= 0 && y < 5)
            {
                i = y * 4 + x;
                switch (m_klotski.m_lpbtData[i])
                {
                case ' ':
                    switch (m_iAdding)
                    {
                    case 0:
                        m_klotski.m_lpbtData[i] = 'o';
                        break;
                    case 1:
                        if (x < 3 && m_klotski.m_lpbtData[i + 1] == ' ')
                        {
                            m_klotski.m_lpbtData[i] = '<';
                            m_klotski.m_lpbtData[i + 1] = '>';
                        }
                        else if (x > 0 && m_klotski.m_lpbtData[i - 1] == ' ')
                        {
                            m_klotski.m_lpbtData[i - 1] = '<';
                            m_klotski.m_lpbtData[i] = '>';
                        }
                        break;
                    case 2:
                        if (y < 4 && m_klotski.m_lpbtData[i + 4] == ' ')
                        {
                            m_klotski.m_lpbtData[i] = '^';
                            m_klotski.m_lpbtData[i + 4] = '_';
                        }
                        else if (y > 0 && m_klotski.m_lpbtData[i - 4] == ' ')
                        {
                            m_klotski.m_lpbtData[i - 4] = '^';
                            m_klotski.m_lpbtData[i] = '_';
                        }
                        break;
                    case 3:
                        if
                        (
                            x < 3 && y < 4 &&
                            m_klotski.m_lpbtData[i + 1] == ' ' &&
                            m_klotski.m_lpbtData[i + 4] == ' ' &&
                            m_klotski.m_lpbtData[i + 5] == ' '
                        )
                        {
                            m_klotski.m_lpbtData[i] = 'p';
                            m_klotski.m_lpbtData[i + 1] = 'q';
                            m_klotski.m_lpbtData[i + 4] = 'b';
                            m_klotski.m_lpbtData[i + 5] = 'd';
                        }
                        else if
                        (
                            x > 0 && y < 4 &&
                            m_klotski.m_lpbtData[i - 1] == ' ' &&
                            m_klotski.m_lpbtData[i + 3] == ' ' &&
                            m_klotski.m_lpbtData[i + 4] == ' '
                        )
                        {
                            m_klotski.m_lpbtData[i - 1] = 'p';
                            m_klotski.m_lpbtData[i] = 'q';
                            m_klotski.m_lpbtData[i + 3] = 'b';
                            m_klotski.m_lpbtData[i + 4] = 'd';
                        }
                        else if
                        (
                            x < 3 && y > 0 &&
                            m_klotski.m_lpbtData[i - 4] == ' ' &&
                            m_klotski.m_lpbtData[i - 3] == ' ' &&
                            m_klotski.m_lpbtData[i + 1] == ' '
                        )
                        {
                            m_klotski.m_lpbtData[i - 4] = 'p';
                            m_klotski.m_lpbtData[i - 3] = 'q';
                            m_klotski.m_lpbtData[i] = 'b';
                            m_klotski.m_lpbtData[i + 1] = 'd';
                        }
                        else if
                        (
                            x > 0 && y > 0 &&
                            m_klotski.m_lpbtData[i - 5] == ' ' &&
                            m_klotski.m_lpbtData[i - 4] == ' ' &&
                            m_klotski.m_lpbtData[i - 1] == ' '
                        )
                        {
                            m_klotski.m_lpbtData[i - 5] = 'p';
                            m_klotski.m_lpbtData[i - 4] = 'q';
                            m_klotski.m_lpbtData[i - 1] = 'b';
                            m_klotski.m_lpbtData[i] = 'd';
                        }
                        break;
                    }
                    break;
                case 'o':
                    m_klotski.m_lpbtData[i] = ' ';
                    break;
                case '^':
                    m_klotski.m_lpbtData[i] = ' ';
                    m_klotski.m_lpbtData[i + 4] = ' ';
                    break;
                case '_':
                    m_klotski.m_lpbtData[i] = ' ';
                    m_klotski.m_lpbtData[i - 4] = ' ';
                    break;
                case '<':
                    m_klotski.m_lpbtData[i] = ' ';
                    m_klotski.m_lpbtData[i + 1] = ' ';
                    break;
                case '>':
                    m_klotski.m_lpbtData[i] = ' ';
                    m_klotski.m_lpbtData[i - 1] = ' ';
                    break;
                case 'p':
                    m_klotski.m_lpbtData[i] = ' ';
                    m_klotski.m_lpbtData[i + 1] = ' ';
                    m_klotski.m_lpbtData[i + 4] = ' ';
                    m_klotski.m_lpbtData[i + 5] = ' ';
                    break;
                case 'q':
                    m_klotski.m_lpbtData[i] = ' ';
                    m_klotski.m_lpbtData[i - 1] = ' ';
                    m_klotski.m_lpbtData[i + 4] = ' ';
                    m_klotski.m_lpbtData[i + 3] = ' ';
                    break;
                case 'b':
                    m_klotski.m_lpbtData[i] = ' ';
                    m_klotski.m_lpbtData[i - 4] = ' ';
                    m_klotski.m_lpbtData[i + 1] = ' ';
                    m_klotski.m_lpbtData[i - 3] = ' ';
                    break;
                case 'd':
                    m_klotski.m_lpbtData[i] = ' ';
                    m_klotski.m_lpbtData[i - 5] = ' ';
                    m_klotski.m_lpbtData[i - 4] = ' ';
                    m_klotski.m_lpbtData[i - 1] = ' ';
                    break;
                }
            }
            else
            {
                for (i = 0; i < 4; ++i)
                {
                    if
                    (
                        x_mouse > m_lpRects[i].left &&
                        x_mouse < m_lpRects[i].right &&
                        y_mouse > m_lpRects[i].top &&
                        y_mouse < m_lpRects[i].bottom
                    )
                    {
                        m_iAdding = i;
                    }
                }
            }
        }
        else
        {
            if (x >= 0 && x < 4 && y >= 0 && y < 5)
            {
                i = y * 4 + x;
                switch (m_klotski.m_lpbtData[i])
                {
                case ' ':
                    if (m_iSelect >= 0 && m_iSelect < 20)
                    {
                        m_iSelect = m_klotski.m_fnMove(m_iSelect, i);
                    }
                    break;
                case 'o':
                case '<':
                case '^':
                case 'p':
                    m_iSelect = i;
                    break;
                case '_':
                case 'b':
                    m_iSelect = i - 4;
                    break;
                case '>':
                case 'q':
                    m_iSelect = i - 1;
                    break;
                case 'd':
                    m_iSelect = i - 5;
                    break;
                }
            }
        }
    }
}

void CCanvas::OnPaint(HDC &hdc)
{
    int i, x, y;
    bool bDraw;
    char lpstrTip[256];
    RECT rect;
    SelectObject(hdc, GetStockObject(BLACK_PEN));
    for (i = 0; i < 20; ++i)
    {
        x = i % 4;
        y = i / 4;
        switch(m_klotski.m_lpbtData[i])
        {
        case 'o':
            rect.left = LEFT_X + x * GRID_SIZE + 3;
            rect.top = TOP_Y + y * GRID_SIZE + 3;
            rect.right = rect.left + GRID_SIZE - 6;
            rect.bottom = rect.top + GRID_SIZE - 6;
            bDraw = true;
            break;
        case '<':
            rect.left = LEFT_X + x * GRID_SIZE + 3;
            rect.top = TOP_Y + y * GRID_SIZE + 3;
            rect.right = rect.left + GRID_SIZE * 2 - 6;
            rect.bottom = rect.top + GRID_SIZE - 6;
            bDraw = true;
            break;
        case '^':
            rect.left = LEFT_X + x * GRID_SIZE + 3;
            rect.top = TOP_Y + y * GRID_SIZE + 3;
            rect.right = rect.left + GRID_SIZE - 6;
            rect.bottom = rect.top + GRID_SIZE * 2 - 6;
            bDraw = true;
            break;
        case 'p':
            rect.left = LEFT_X + x * GRID_SIZE + 3;
            rect.top = TOP_Y + y * GRID_SIZE + 3;
            rect.right = rect.left + GRID_SIZE * 2 - 6;
            rect.bottom = rect.top + GRID_SIZE * 2 - 6;
            bDraw = true;
            break;
        default:
            bDraw = false;
        }
        if (bDraw)
        {
            if (i == m_iSelect)
            {
                SelectObject(hdc, GetStockObject(GRAY_BRUSH));
            }
            else
            {
                SelectObject(hdc, GetStockObject(WHITE_BRUSH));
            }
            Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
        }
    }
    MoveToEx(hdc, LEFT_X + GRID_SIZE, TOP_Y, NULL);
    LineTo(hdc, LEFT_X, TOP_Y);
    LineTo(hdc, LEFT_X, TOP_Y + GRID_SIZE * 5);
    LineTo(hdc, LEFT_X + GRID_SIZE * 4, TOP_Y + GRID_SIZE * 5);
    LineTo(hdc, LEFT_X + GRID_SIZE * 4, TOP_Y);
    LineTo(hdc, LEFT_X + GRID_SIZE * 3, TOP_Y);
    rect.left = 420;
    rect.right = 580;
    rect.top = TOP_Y;
    rect.bottom = TOP_Y + 30;
    wsprintf(lpstrTip, "Vertices: %d", m_klotski.m_iVertices);
    DrawText(hdc, lpstrTip, strlen(lpstrTip), &rect, DT_LEFT);
    wsprintf(lpstrTip, "Queue: %d", m_klotski.m_iQueueSize);
    rect.top = TOP_Y + 60;
    rect.bottom = TOP_Y + 90;
    DrawText(hdc, lpstrTip, strlen(lpstrTip), &rect, DT_LEFT);
    wsprintf(lpstrTip, "Solution: %d/%d", m_klotski.m_iStep, m_klotski.m_vecSolution.size());
    rect.top = TOP_Y + 120;
    rect.bottom = TOP_Y + 150;
    DrawText(hdc, lpstrTip, strlen(lpstrTip), &rect, DT_LEFT);
    if (m_bEditing)
    {
        for (i = 0; i < 4; ++i)
        {
            if (m_iAdding == i)
            {
                SelectObject(hdc, GetStockObject(GRAY_BRUSH));
            }
            else
            {
                SelectObject(hdc, GetStockObject(WHITE_BRUSH));
            }
            Rectangle(hdc, m_lpRects[i].left, m_lpRects[i].top, m_lpRects[i].right, m_lpRects[i].bottom);
        }
    }
}
